package com.gc.controller;

import com.gc.common.constants.FileConstants;
import com.gc.common.constants.SysConstants;
import com.gc.common.resp.ApiResult;
import com.gc.common.util.MyUtil;
import com.gc.common.util.QrCodeUtils;
import com.gc.dto.AuditDTO;
import com.gc.dto.VorDTO;
import com.gc.dto.VorSubmitDTO;
import com.gc.pojo.*;
import com.gc.services.*;
import com.sun.org.apache.regexp.internal.RE;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author xyl
 * @create 2020/7/25 14:19
 * @desc vor : vei-origin-record  (vei:vehicle-emissions-inspection)
 **/
@Slf4j
@Controller
@RequestMapping("vor")
public class VorController {

    @Autowired
    private VorService vorService;
    @Autowired
    private TemplateService templateService;
    @Autowired
    private ClientService clientService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private UserService userService;
    @Autowired
    private VorAuditService vorAuditService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private EntrustService entrustService;
    @Autowired
    private UserAssociationService userAssociationService;

    /**
     * 页面跳转 , 跳转到填写原始记录页面 , 如果携带的有原始记录id , 则查询该原始记录, 并填充填写页面 , 用于保存查看修改
     *
     * @param vid
     * @return
     */
    @RequestMapping("submit-view")
    public ModelAndView toView(@RequestParam(required = false) Integer vid) {
        Subject subject = SecurityUtils.getSubject();
        SysUser curUser = (SysUser) subject.getPrincipal();
        ModelAndView mav = new ModelAndView("vor/submit");
        SysDevice device = deviceService.getDeviceById(userAssociationService.getByUserId(curUser.getUserId()).getDeviceId());
        mav.addObject("device",device);
        //vid不为空 , 说明是填充原始记录提交页面的内容. (点击查看保存时的跳转)
        if (null != vid) {

            SysVor sysVor;
            if (subject.hasRole(SysConstants.SYS_ROLE5)) {
                sysVor = vorService.getVorByVidAndUid(vid, curUser.getUserId());
            } else {
                sysVor = vorService.getVorByVid(vid);
            }
            mav.addObject("vor", sysVor);
        }
        return mav;
    }

    /**
     * 保存原始记录
     *
     * @param sysVor 原始记录类
     * @return 自定义响应体
     */
    @PostMapping("save")
    @ResponseBody
    public ApiResult save(@RequestBody SysVor sysVor) {
        Subject subject = SecurityUtils.getSubject();
        SysUser curUser = (SysUser) subject.getPrincipal();
        int count;
        ApiResult result = new ApiResult();
        if (ObjectUtils.isEmpty(sysVor)) {
            return new ApiResult(200, "请填写数据");
        }
        if (!(subject.hasRole(SysConstants.SYS_ROLE1) || subject.hasRole(SysConstants.SYS_ROLE3) || subject.hasRole(SysConstants.SYS_ROLE4))) {
            //获取报告状态 , 查看是否可修改
            if (!ObjectUtils.isEmpty(sysVor.getVorId())) {
                SysVor vor = vorService.getVorByVid(sysVor.getVorId());
                if (vor.getVorStatus() == SysConstants.VOR_STATUS2 || vor.getVorStatus() == SysConstants.VOR_STATUS4 || vor.getVorStatus() == SysConstants.VOR_STATUS6 || vor.getVorStatus() == SysConstants.VOR_STATUS7) {
                    return new ApiResult(500, "报告无法修改！");
                }
            }
        }
        try {
            //图片转格式
            base64LoadVor(sysVor);
        } catch (Exception e) {
            return new ApiResult(200, "图片转换异常,保存失败");
        }
        //说明报告第一次保存
        if (sysVor.getVorId() == null) {
            //这里执行插入
            sysVor.setUserId(curUser.getUserId());
            sysVor.setTemplateId(SysConstants.TEMPLATE_NULL_ID);        //设置模板空模板
            sysVor.setCreateTime(new Date());
            sysVor.setVorStatus(SysConstants.VOR_STATUS0);
            count = vorService.addVor(sysVor);
        } else {
            //todo 删除之前报告
            count = vorService.modifyVor(sysVor);
        }
        if (count >= 1) {
            result.setData(sysVor.getVorId());
        } else {
            result.setMessage("数据上传异常!");
        }
        return result;
    }

    /**
     * 对接安卓接口 , 安卓提交原始记录接口
     *
     * @return
     */
    @PostMapping("/android/save")
    @ResponseBody
    public ApiResult androidSave(@RequestBody SysVor sysVor) {
        ApiResult result = new ApiResult();
        try {
            //图片转格式
            base64LoadVor(sysVor);
        } catch (Exception e) {
            return new ApiResult(200, "图片转换异常,保存失败");
        }
        //安卓未对接登录接口 ,这里就使用默认用户 , android
        sysVor.setUserId(SysConstants.DEFAULT_ANDROID_USER_ID);
        sysVor.setTemplateId(SysConstants.TEMPLATE_NULL_ID);        //设置模板空模板
        sysVor.setCreateTime(new Date());
        sysVor.setVorStatus(SysConstants.VOR_STATUS0);
        int count = vorService.addVor(sysVor);
        result.setData(sysVor.getVorId());
        return result;
    }
    /**
     * 对接安卓接口 , 安卓提交原始记录接口
     *
     * @return
     */
    @PostMapping("/android/modify")
    @ResponseBody
    public ApiResult androidSaveImage(@RequestBody SysVor sysVor) {
        try {
            //图片转格式
            base64LoadVor(sysVor);
        } catch (Exception e) {
            return new ApiResult(200, "图片转换异常,保存失败");
        }
        if(ObjectUtils.isEmpty(sysVor.getVorId())){
            return new ApiResult(500,"vorId为空 , 无法有效对应数据");
        }
        if(ObjectUtils.isEmpty(vorService.getVorByVid(sysVor.getVorId()))){
            return new ApiResult(500,"无法对应到vorId的数据");
        }
        int count = vorService.modifyVor(sysVor);
        return new ApiResult();
    }


    @PostMapping("submit")
    @ResponseBody
    public ApiResult submit(@RequestBody @Validated VorSubmitDTO vorSubmitDTO) {
        SysVor vor = vorService.getVorByVid(vorSubmitDTO.getVorId());
        SysVorAudit audit = new SysVorAudit();
        audit.setVorId(vorSubmitDTO.getVorId());
        audit.setAuditBy(vorSubmitDTO.getShyId());
        audit.setRatifyBy(vorSubmitDTO.getQfyId());
        audit.setCreateTime(new Date());
        if (vor.getVorStatus() == SysConstants.VOR_STATUS5 || vor.getVorStatus() == SysConstants.VOR_STATUS3 || vor.getVorStatus() == SysConstants.VOR_STATUS1) {
            int count1 = vorService.modifyVorStatusByVId(vorSubmitDTO.getVorId(), SysConstants.VOR_STATUS1);
            SysVorAudit vorAudit = vorAuditService.getByVorId(vor.getVorId());
            audit.setAuditId(vorAudit.getAuditId());
            int count2 = vorAuditService.modify(audit);
        } else if (vor.getVorStatus() == SysConstants.VOR_STATUS0) {
            int count1 = vorService.modifyVorStatusByVId(vorSubmitDTO.getVorId(), SysConstants.VOR_STATUS1);
            int count2 = vorAuditService.add(audit);
        } else {
            return new ApiResult(200, "此报告状态不支持提交！");
        }
        return new ApiResult();
    }

    /**
     * 页面跳转,原始记录
     */
    @GetMapping("/user/list-view")
    public ModelAndView myVorListView(@RequestParam(required = false) Integer status) {
        ModelAndView mav = new ModelAndView("vor/user/list");
        mav.addObject("shys", userService.getShy());
        mav.addObject("qfys", userService.getQfy());
        mav.addObject("clients", clientService.getAllClient());
        mav.addObject("status", status);
        return mav;
    }

    /**
     * 管理员页面跳转
     */
    @GetMapping("/admin/list-view")
    public ModelAndView manageListView(@RequestParam(required = false) Integer status) {
        ModelAndView mav = new ModelAndView("vor/admin/list");
        mav.addObject("clients", clientService.getAllClient());
        mav.addObject("status", status);
        return mav;
    }

    /**
     * 获取原始记录列表 , 根据携带的权限 显示不同的列表
     *
     * @param cid    clientId
     * @param status 状态
     * @return
     */
    @GetMapping("getList")
    @ResponseBody
    public List<VorDTO> getMyVorList(@RequestParam(required = false) Integer cid,
                                     @RequestParam(required = false) Integer status) {
        Subject subject = SecurityUtils.getSubject();
        SysUser curUser = (SysUser) subject.getPrincipal();
        //如果是现场人员角色 , 只查询自己填写的原始记录即可 . 如果是系统管理员查询所有用户的原始记录单
        List<VorDTO> list = null;
        if (subject.hasRole(SysConstants.SYS_ROLE5) || subject.hasRole(SysConstants.SYS_ROLE6)) {
            if (null != cid && cid != 0) {
                list = vorService.getVorByCid(curUser.getUserId(), cid);
            } else {
                list = vorService.getMyVorList(curUser.getUserId());
            }
            //当status 为空时，就是查询所有 非保存状态的报告
            if (ObjectUtils.isEmpty(status)) {
                list = list.stream().filter(vorDTO -> SysConstants.VOR_STATUS0 != vorDTO.getVorStatus()).collect(Collectors.toList());
            }
        } else {
            if (subject.hasRole(SysConstants.SYS_ROLE3) && !ObjectUtils.isEmpty(status) && SysConstants.VOR_STATUS2 == status) {
                list = vorService.getQfyVor(curUser.getUserId());
            } else if (subject.hasRole(SysConstants.SYS_ROLE4) && !ObjectUtils.isEmpty(status) && SysConstants.VOR_STATUS1 == status) {
                list = vorService.getShyVor(curUser.getUserId());
            } else {
                if (!ObjectUtils.isEmpty(status) && status == 0) {
                    list = vorService.getAllVorList();
                    list = list.stream().filter(vorDTO -> vorDTO.getUserId().equals(curUser.getUserId())).collect(Collectors.toList());
                } else {
                    list = vorService.getNotSaveVorList();
                }
            }
            if (!ObjectUtils.isEmpty(cid) && cid != 0) {
                list = list.stream().filter((vor) -> cid.equals(vor.getClientId())).collect(Collectors.toList());
            }
        }
        if (!ObjectUtils.isEmpty(status)) {
            list = list.stream().filter(vorDTO -> status.equals(vorDTO.getVorStatus())).collect(Collectors.toList());
        }
        return list;
    }

    /**
     * 获取单个原始记录,用于modal弹出框 查看信息
     *
     * @param vid
     * @return
     */
    @GetMapping("get")
    @ResponseBody
    public SysVor get(@RequestParam Integer vid) {
        return vorService.getVorByVid(vid);
    }

    /**
     * 删除单个原始记录
     *
     * @param vid 原始记录id
     */
    @PostMapping("remove")
    @ResponseBody
    public ApiResult removeVor(Integer vid) {
        ApiResult result = new ApiResult();
        SysVor vor = vorService.getVorByVid(vid);
        if (vor.getVorStatus() == SysConstants.VOR_STATUS2 || vor.getVorStatus() == SysConstants.VOR_STATUS4 || vor.getVorStatus() == SysConstants.VOR_STATUS6 || vor.getVorStatus() == SysConstants.VOR_STATUS7) {
            return new ApiResult(500, "报告无法删除！");
        }
        delLocalImages(vor);
        int count = vorService.removeVorByVId(vid);
        return result;
    }

    /**
     * 修改原始记录模板 , 管理员权限
     *
     * @param vid 原始记录id
     * @param tid 模板id
     */
    @PostMapping("modify")
    @ResponseBody
    public ApiResult modify(@RequestParam Integer vid, @RequestParam Integer tid) {
        ApiResult result = new ApiResult();
        int count = vorService.modifyVorTid(tid, vid);
        if (count == 0) {
            log.error("修改模板失败!");
            return new ApiResult(200, "请求失败!");
        }
        return result;
    }

    @PostMapping("audit")
    @ResponseBody
    @Transactional
    public ApiResult reportPass(@RequestBody AuditDTO auditDTO) {
        Subject subject = SecurityUtils.getSubject();
        boolean con = false;
        if (subject.hasRole(SysConstants.SYS_ROLE1)) {
            con = true;
        } else {
            //状态 和 角色的判断
            if (auditDTO.getStatus() == SysConstants.VOR_STATUS2 || auditDTO.getStatus() == SysConstants.VOR_STATUS3) {
                if (subject.hasRole(SysConstants.SYS_ROLE4)) {
                    con = true;
                }
            }
            if (auditDTO.getStatus() == SysConstants.VOR_STATUS4 || auditDTO.getStatus() == SysConstants.VOR_STATUS5) {
                if (subject.hasRole(SysConstants.SYS_ROLE3)) {
                    con = true;
                }
            }
        }
        if (auditDTO.getStatus() == SysConstants.VOR_STATUS4) {
            //如果缓慢的话 , 可开启线程
            SysVor vor = vorService.getVorByVid(auditDTO.getVorId());
            //生成报告编号
            StringBuffer bgbh = vorService.generatorReportNumber(vor);
            //生成委托记录
            SysEntrust entrust = vorService.generatorEntrustRecord(vor);
            //生成设备使用记录
            SysDeviceUse use = vorService.generatorDeviceRecord(vor);
            try {
                QrCodeUtils.encode(SysConstants.QRCODE_URL + auditDTO.getVorId(), "", FileConstants.QRCODE_IMG_LOCAL_URL, bgbh + ".png", false);
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                int count1 = vorService.modifyReportNumber(vor.getVorId(), bgbh.toString()); //修改报告编号
                int count2 = entrustService.addEntrust(entrust);  //插入
                int count3 = deviceService.addDeviceUse(use);   //插入
            } catch (RuntimeException e) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                e.printStackTrace();
            }
        }
        if (con) {
            int count = vorService.auditReport(auditDTO);
            return new ApiResult();
        } else {
            return new ApiResult(500, "非法操作！");
        }
    }

    @PostMapping("archive")
    @ResponseBody
    public ApiResult archive(@RequestBody AuditDTO auditDTO) {
        Subject subject = SecurityUtils.getSubject();
        if (subject.hasRole(SysConstants.SYS_ROLE1)) {
            return new ApiResult(500, "非法请求！");
        }
        int count1 = vorService.modifyVorStatusByVId(auditDTO.getVorId(), auditDTO.getStatus());
        return new ApiResult();
    }

    @GetMapping("getRejectMsg")
    @ResponseBody
    public ApiResult getRejectMsg(@RequestParam Integer vorId) {
        SysVorAudit audit = vorAuditService.getByVorId(vorId);
        SysVor vor = vorService.getVorByVid(vorId);
        if (vor.getVorStatus() == SysConstants.REPORT_STATUS5) {
            return new ApiResult(200, audit.getRatifyMsg());
        } else if (vor.getVorStatus() == SysConstants.REPORT_STATUS3) {
            return new ApiResult(200, audit.getAuditMsg());
        }
        return new ApiResult();
    }

    @GetMapping("down")
    public void down(@RequestParam Integer vorId, HttpServletResponse response) {
        SysVor vor = vorService.getVorByVid(vorId);
        if (ObjectUtils.isEmpty(vor)) {
            return;
        }
        //根据当前用户所关联的 客户中的报告id
        int templateId = 8;
        SysUserAssociation as = userAssociationService.getByUserId(vor.getUserId());
        if (as.getRoles().equals(SysConstants.SYS_ROLE05+"")) {
            templateId =userAssociationService.getByUserId(vor.getUserId()).getTemplateId();
        }else if(as.getRoles().equals(SysConstants.SYS_ROLE06+"")){
            templateId = templateService.getTemplateByUserId(vor.getUserId()).getTemplateId();
        }
        if (templateId == 8) {
            vorService.downVorExcel1(vor, response);
        } else if (templateId == 9) {
            vorService.downVorExcel2(vor, response);
        }else if(templateId == 10){
            vorService.downVorExcel3(vor, response);
        }else{
            vorService.downVorExcel1(vor, response);
        }

    }

    /**
     * 用于原始记录提交时 , 缺少之前保存过的图片时, 删除之前的本地文件
     */
    private void delLocalImages(SysVor vor) {
        delLocalImage(vor.getZpClmp());
        delLocalImage(vor.getZpFdjmp());
        delLocalImage(vor.getZpHclzz());
        delLocalImage(vor.getZpJxzt());
        delLocalImage(vor.getZpJcjg());
        delLocalImage(vor.getZpSbjc());
    }

    private void delLocalImage(String fileName) {
        if (!StringUtils.isEmpty(fileName)) {
            File file = new File(FileConstants.VOR_IMG_LOCAL_URL + fileName);
            if (file.exists()) {
                file.delete();
            }
        }
    }

    /**
     * 二维码页面 ， 这里可能需要做一个 校验 ， 防止恶意访问
     *
     * @param vid
     * @return
     */
    @GetMapping("qrcode")
    public ModelAndView qrCode(@RequestParam Integer vid) {
        ModelAndView mav = new ModelAndView("qrcode");
        SysVor vor = vorService.getVorByVid(vid);
        mav.addObject("vor", vor);
        return mav;
    }


    /**
     * base64转图片 , 并存本地
     *
     * @param sysVor
     */
    private void base64LoadVor(SysVor sysVor) {
        String s1 = MyUtil.Base64ToImage(sysVor.getZpSbjc(), FileConstants.VOR_IMG_LOCAL_URL);
        String s2 = MyUtil.Base64ToImage(sysVor.getZpClmp(), FileConstants.VOR_IMG_LOCAL_URL);
        String s3 = MyUtil.Base64ToImage(sysVor.getZpFdjmp(), FileConstants.VOR_IMG_LOCAL_URL);
        String s4 = MyUtil.Base64ToImage(sysVor.getZpHclzz(), FileConstants.VOR_IMG_LOCAL_URL);
        String s5 = MyUtil.Base64ToImage(sysVor.getZpJxzt(), FileConstants.VOR_IMG_LOCAL_URL);
        String s6 = MyUtil.Base64ToImage(sysVor.getZpJcjg(), FileConstants.VOR_IMG_LOCAL_URL);
        sysVor.setZpSbjc(s1);
        sysVor.setZpClmp(s2);
        sysVor.setZpFdjmp(s3);
        sysVor.setZpHclzz(s4);
        sysVor.setZpJxzt(s5);
        sysVor.setZpJcjg(s6);
    }
}
